
/* copyright (c) 1996, 1997, 1998, 1999 William R. Pearson and the
   U. of Virginia */

/* $Name: fasta34t11d4 $ - $Id: manshowun.c,v 1.10 2001/09/17 21:18:18 wrp Exp $ */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#include "defs.h"
#include "param.h"
#include "p_mw.h"

#include "structs.h"

#define MAX_BLINE 200

extern double zs_to_bit(float, int, int);
extern void cal_coord(int n0, int n1, long sq0off, long loffset,
		      struct a_struct *aln);

void showbest (FILE *fp, struct beststr **bptr, int nbest,
	       int qlib, struct mngmsg *m_msg, struct pstruct pst,
	       char *gstring2)
{
  int ntmp = 0;
  char bline[MAX_BLINE], fmt[40], pad[MAX_BLINE], rline[40];
  char stat_str[128];
  int ishow = 0, istop, i = 0, ib;
  int nshow;
  int lsnum;
  int r_margin;
  struct beststr *bbp;
  char *bp, *bp1, *bpn, *tp;
  char sfstr[MAX_FN];

  int qsfnum[10], qsfnum_n[10], isf, nsf, nsf_n;
  char rel_label[12];

#ifdef SHOWREL
  strncpy(rel_label,"related",12);
#else
  strncpy(rel_label,"unrelated",12);
#endif

  if ((bp=strchr(m_msg->libstr,SFCHAR))!=NULL) {
    strncpy(sfstr,bp+1,sizeof(sfstr));
    if ((bp1=strchr(sfstr,SFCHAR)) != NULL) { /* look for second | */
      if ((bpn=strchr(sfstr,NSFCHAR))!=NULL ) *bpn = '\0';
      *bp1='\0';
      tp = strtok(sfstr," \t");
      qsfnum[0]=atoi(tp);
      isf = 1;
      while ((tp=strtok(NULL," \t"))!=NULL) {
	qsfnum[isf++] = atoi(tp);
	if (isf >= 10) {
	  fprintf(stderr," error - too many superfamilies: %d\n %s\n",
		  isf,m_msg->libstr);
	  break;
	}
      }
      qsfnum[nsf=isf]=0;
      sf_sort(qsfnum,nsf);
      /* now get negatives */
      if (bpn != NULL) {
	tp = strtok(bpn+1," \t");
	qsfnum_n[0]=atoi(tp);
	isf = 1;
	while ((tp=strtok(NULL," \t"))!=NULL) {
	  qsfnum_n[isf++] = atoi(tp);
	  if (isf >= 10) {
	    fprintf(stderr,
		    " error - too many negative superfamilies: %d\n %s\n",
		    isf,m_msg->libstr);
	    break;
	  }
	}
	qsfnum_n[nsf_n=isf]=0;
	sf_sort(qsfnum_n,nsf_n);
      }
    }
    else {	/* only one sfnum */
      sscanf(bp+1,"%d",qsfnum);
      qsfnum[1]=0;
      qsfnum_n[0]= nsf_n = 0;
    }
  }
  else {
    fprintf(stderr," no query superfamily number\n %s\n",m_msg->libstr);
    return;
  }

  if (m_msg->aln.llen > MAX_BLINE) m_msg->aln.llen = MAX_BLINE;

  if (pst.zsflag<0) r_margin = 14;
  else if (pst.zsflag<0 && m_msg->nrelv > 1 ) r_margin = 21;
  else r_margin = 10;

#ifndef TFASTA
  sprintf(fmt,"%%-%ds [%%4d](%%4d)",m_msg->aln.llen-r_margin);
#else
  sprintf(fmt,"%%-%ds [%%4d](%%4d)",m_msg->aln.llen-(r_margin+4));
#endif
  memset(pad,' ',m_msg->aln.llen-(r_margin+16));
  pad[m_msg->aln.llen-(r_margin+22)]='\0';

  nshow = 20;
  /* show specified number */
  if (m_msg->mshow != 0) {
    nshow = min (m_msg->mshow, nshow);
  }

  istop = nshow;

  if ((bp = strchr (m_msg->libstr, '\n')) != NULL) *bp = '\0';
  fprintf (fp, "%3d >%s\n", qlib,m_msg->libstr);
  if (pst.zsflag>=0)
      if (m_msg->z_bits==1) {/* show bit score */
	fprintf(fp,"The best %s scores are:%s%s bits E(%ld)\n",
		rel_label,pad,m_msg->label,m_msg->db.entries);
      }
      else {/* show z-score */
	fprintf(fp,"The best %s scores are:%s%s z-sc E(%ld)\n",
		rel_label,pad,m_msg->label,m_msg->db.entries);
      }
  else
    fprintf(fp,"The best %s scores are:%s%s\n",rel_label,pad,m_msg->label);

  if (fp != stdout)
    if (pst.zsflag>=0) {
      if (m_msg->z_bits==1) {/* show bit score */
	fprintf(fp,"The best %s scores are:%s%s bits E(%ld)\n",
		rel_label,pad,m_msg->label,m_msg->db.entries);
      }
      else {/* show z-score */
	fprintf(fp,"The best %s scores are:%s%s z-sc E(%ld)\n",
		rel_label,pad,m_msg->label,m_msg->db.entries);
      }
    }
    else
      printf("The best %s scores are:%s%s\n",rel_label,pad,m_msg->label);
  
  ishow = 0;

  ib = 0;
l1:
  while( ishow < nshow && ib<nbest) {
    bbp = bptr[ib++];
    if (pst.zsflag>=0 && bbp->escore < m_msg->e_low) continue;
    if (pst.zsflag>=0 && bbp->escore >= m_msg->e_cut) break;
    if (sfn_cmp(qsfnum_n,bbp->desptr->sfnum)) continue;
#ifndef SHOWREL
    if (sfn_cmp(qsfnum,bbp->desptr->sfnum)) continue;
#else
    if (!sfn_cmp(qsfnum,bbp->desptr->sfnum)) continue;
#endif
    ishow++;

    strncpy(bline,bbp->desptr->bline,m_msg->aln.llen-r_margin);

#ifndef TFASTA
    bline[m_msg->aln.llen-r_margin]='\0';
#else
    bline[m_msg->aln.llen-(r_margin+4)]='\0';
#endif

    fprintf (fp, fmt,bp=bline,bbp->desptr->sfnum[0],bbp->n1);

  if (m_msg->srelv == 1) 
    fprintf (fp, " %4d", bbp->score[pst.score_ix]);
  else if (m_msg->srelv > 0) fprintf (fp, " %4d", bbp->score[0]);
  if (m_msg->srelv > 1) fprintf (fp, " %4d", bbp->score[1]);
  if (m_msg->srelv > 2) fprintf (fp, " %4d", bbp->score[2]);
  if (pst.zsflag>=0) {
    if (m_msg->z_bits==1) 
      fprintf (fp, " %4.0f %7.2lg",zs_to_bit(bbp->zscore,m_msg->n0,bbp->n1),bbp->escore);
    else
      fprintf (fp, " %4.1f %7.2lg",bbp->zscore,bbp->escore);
  }

    if (m_msg->markx == 9) {
      cal_coord(m_msg->n0,bbp->n1,m_msg->sq0off,bbp->desptr->loffset,bbp->aln_d);
      fprintf(fp,"\t%5.3f %5.3f %4d %4d %4ld %4ld %4ld %4ld %3d %3d",
	      bbp->percent/100.0,bbp->gpercent/100.0, bbp->swscore,
	      bbp->aln_d->a_len,
	      bbp->aln_d->d_start0,bbp->aln_d->d_stop0,
	      bbp->aln_d->d_start1,bbp->aln_d->d_stop1,
	      bbp->aln_d->ngap_q,bbp->aln_d->ngap_l);
    }
    fprintf (fp, "\n");
    fflush(fp);

  }
  if (ib < nbest && pst.zsflag>=0 && bbp->escore < m_msg->e_cut ) {
    if (m_msg->mshow_flg && istop < m_msg->mshow) {
      nshow += 10;
      goto l1;
    }
  }
}

showalign()
{}


#if !defined(MPI_SRC) && !defined(PV_MP4)
sf_sort(s,n)
     int *s, n;
{
  int gap, i, j;
  int itmp;
	
  for (i=0; i<n-1; i++)
    if (s[i]>s[i+1]) goto l2;
  return;

l2:
  for (gap=n/2; gap>0; gap/=2)
    for (i=gap; i<n; i++)
      for (j=i-gap; j>=0; j -= gap) {
	if (s[j] <= s[j+gap]) break;
	itmp = s[j];
	s[j]=s[j+gap];
	s[j+gap]=itmp;
      }
}
#endif

sf1_cmp(int *q, int *s)
{
  if (*q ==0) return 0;

  while (*s++) {
    if (*q == *s) return *s;
  }
  return 0;
}
